package com.ming.core.builder;

import java.util.LinkedHashMap;
import java.util.Map;

public class FlowBuilderContext {

    private FlowType flowType;

    private Map<String,String> mappingMap = new LinkedHashMap<>();
    private Map<String,String> mappingNodeMap = new LinkedHashMap<>();
    private Map<String,String> mappingEdgeMap = new LinkedHashMap<>();

    public static final String NODES = "nodes";
    public static final String EDGES = "edges";
    public static final String NODE_ID = "id";
    public static final String NODE_TYPE = "type";
    public static final String NODE_LABEL = "label";
    public static final String NODE_DATA = "data";
    public static final String EDGE_ID = "id";
    public static final String EDGE_TYPE = "type";
    public static final String EDGE_SOURCE = "source";
    public static final String EDGE_TARGET = "target";
    public static final String EDGE_DATA = "data";

    private FlowBuilderContext() {
    }

    public static FlowBuilderContext NEW() {
        return new FlowBuilderContext();
    }

    public FlowBuilderContext flowType(FlowType flowType) {
        this.flowType = flowType;
        return this;
    }

    public FlowBuilderContext addMapping(String key, String value) {
        mappingMap.put(key, value);
        return this;
    }

    public FlowBuilderContext addMappingNodes(String value) {
        mappingMap.put(NODES, value);
        return this;
    }

    public String getMappingNodes() {
        return mappingMap.get(NODES);
    }

    public FlowBuilderContext addMappingEdges(String value) {
        mappingMap.put(EDGES, value);
        return this;
    }

    public String getMappingEdges() {
        return mappingMap.get(EDGES);
    }

    public FlowBuilderContext addMappingNodeId(String value) {
        mappingNodeMap.put(NODE_ID, value);
        return this;
    }

    public String getMappingNodeId() {
        return mappingNodeMap.get(NODE_ID);
    }

    public FlowBuilderContext addMappingNodeType(String value) {
        mappingNodeMap.put(NODE_TYPE, value);
        return this;
    }

    public String getMappingNodeType() {
        return mappingNodeMap.get(NODE_TYPE);
    }

    public FlowBuilderContext addMappingNodeLabel(String value) {
        mappingNodeMap.put(NODE_LABEL, value);
        return this;
    }

    public String getMappingNodeLabel() {
        return mappingNodeMap.get(NODE_LABEL);
    }

    public FlowBuilderContext addMappingNodeData(String value) {
        mappingNodeMap.put(NODE_DATA, value);
        return this;
    }

    public String getMappingNodeData() {
        return mappingNodeMap.get(NODE_DATA);
    }

    public FlowBuilderContext addMappingEdgeId(String value) {
        mappingEdgeMap.put(EDGE_ID, value);
        return this;
    }

    public String getMappingEdgeId() {
        return mappingEdgeMap.get(EDGE_ID);
    }

    public FlowBuilderContext addMappingEdgeType(String value) {
        mappingEdgeMap.put(EDGE_TYPE, value);
        return this;
    }

    public String getMappingEdgeType() {
        return mappingEdgeMap.get(EDGE_TYPE);
    }

    public FlowBuilderContext addMappingEdgeSource(String value) {
        mappingEdgeMap.put(EDGE_SOURCE, value);
        return this;
    }

    public String getMappingEdgeSource() {
        return mappingEdgeMap.get(EDGE_SOURCE);
    }

    public FlowBuilderContext addMappingEdgeTarget(String value) {
        mappingEdgeMap.put(EDGE_TARGET, value);
        return this;
    }

    public String getMappingEdgeTarget() {
        return mappingEdgeMap.get(EDGE_TARGET);
    }

    public FlowBuilderContext addMappingEdgeData(String value) {
        mappingEdgeMap.put(EDGE_DATA, value);
        return this;
    }

    public String getMappingEdgeData() {
        return mappingEdgeMap.get(EDGE_DATA);
    }

    public FlowBuilder getFlowBuilder() {
        switch (flowType.name()){
            case "LOGIC_FLOW":
                return new LogicFlowBuilder().context(this);
            case "VUE_FLOW":
                return new VueFlowBuilder().context(this);
            case "CUSTOM_FLOW":
                return new CustomFlowBuilder().context(this);
            default:
                return null;
        }
    }

}
